{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 忽略警告信息\n",
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 数据集的准备"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1460, 82)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train = pd.read_csv('datas/house_data.csv')\n",
    "y = train['SalePrice']\n",
    "train.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1460, 80)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train1 = train.drop(['Id', 'SalePrice'], axis=1)\n",
    "train1.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>MSSubClass</th>\n",
       "      <th>LotFrontage</th>\n",
       "      <th>LotArea</th>\n",
       "      <th>OverallQual</th>\n",
       "      <th>OverallCond</th>\n",
       "      <th>YearBuilt</th>\n",
       "      <th>YearRemodAdd</th>\n",
       "      <th>MasVnrArea</th>\n",
       "      <th>BsmtFinSF1</th>\n",
       "      <th>BsmtFinSF2</th>\n",
       "      <th>...</th>\n",
       "      <th>SaleType_ConLw</th>\n",
       "      <th>SaleType_New</th>\n",
       "      <th>SaleType_Oth</th>\n",
       "      <th>SaleType_WD</th>\n",
       "      <th>SaleCondition_Abnorml</th>\n",
       "      <th>SaleCondition_AdjLand</th>\n",
       "      <th>SaleCondition_Alloca</th>\n",
       "      <th>SaleCondition_Family</th>\n",
       "      <th>SaleCondition_Normal</th>\n",
       "      <th>SaleCondition_Partial</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>60</td>\n",
       "      <td>65.0</td>\n",
       "      <td>8450</td>\n",
       "      <td>7</td>\n",
       "      <td>5</td>\n",
       "      <td>2003</td>\n",
       "      <td>2003</td>\n",
       "      <td>196.0</td>\n",
       "      <td>706</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>20</td>\n",
       "      <td>80.0</td>\n",
       "      <td>9600</td>\n",
       "      <td>6</td>\n",
       "      <td>8</td>\n",
       "      <td>1976</td>\n",
       "      <td>1976</td>\n",
       "      <td>0.0</td>\n",
       "      <td>978</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>60</td>\n",
       "      <td>68.0</td>\n",
       "      <td>11250</td>\n",
       "      <td>7</td>\n",
       "      <td>5</td>\n",
       "      <td>2001</td>\n",
       "      <td>2002</td>\n",
       "      <td>162.0</td>\n",
       "      <td>486</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>70</td>\n",
       "      <td>60.0</td>\n",
       "      <td>9550</td>\n",
       "      <td>7</td>\n",
       "      <td>5</td>\n",
       "      <td>1915</td>\n",
       "      <td>1970</td>\n",
       "      <td>0.0</td>\n",
       "      <td>216</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>60</td>\n",
       "      <td>84.0</td>\n",
       "      <td>14260</td>\n",
       "      <td>8</td>\n",
       "      <td>5</td>\n",
       "      <td>2000</td>\n",
       "      <td>2000</td>\n",
       "      <td>350.0</td>\n",
       "      <td>655</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 303 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "   MSSubClass  LotFrontage  LotArea  OverallQual  OverallCond  YearBuilt  \\\n",
       "0          60         65.0     8450            7            5       2003   \n",
       "1          20         80.0     9600            6            8       1976   \n",
       "2          60         68.0    11250            7            5       2001   \n",
       "3          70         60.0     9550            7            5       1915   \n",
       "4          60         84.0    14260            8            5       2000   \n",
       "\n",
       "   YearRemodAdd  MasVnrArea  BsmtFinSF1  BsmtFinSF2          ...            \\\n",
       "0          2003       196.0         706           0          ...             \n",
       "1          1976         0.0         978           0          ...             \n",
       "2          2002       162.0         486           0          ...             \n",
       "3          1970         0.0         216           0          ...             \n",
       "4          2000       350.0         655           0          ...             \n",
       "\n",
       "   SaleType_ConLw  SaleType_New  SaleType_Oth  SaleType_WD  \\\n",
       "0               0             0             0            1   \n",
       "1               0             0             0            1   \n",
       "2               0             0             0            1   \n",
       "3               0             0             0            1   \n",
       "4               0             0             0            1   \n",
       "\n",
       "   SaleCondition_Abnorml  SaleCondition_AdjLand  SaleCondition_Alloca  \\\n",
       "0                      0                      0                     0   \n",
       "1                      0                      0                     0   \n",
       "2                      0                      0                     0   \n",
       "3                      1                      0                     0   \n",
       "4                      0                      0                     0   \n",
       "\n",
       "   SaleCondition_Family  SaleCondition_Normal  SaleCondition_Partial  \n",
       "0                     0                     1                      0  \n",
       "1                     0                     1                      0  \n",
       "2                     0                     1                      0  \n",
       "3                     0                     0                      0  \n",
       "4                     0                     1                      0  \n",
       "\n",
       "[5 rows x 303 columns]"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 变成one_hot形式，内容全部被数字化了,原特征删除\n",
    "X = pd.get_dummies(train1).reset_index(drop=True)\n",
    "X.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2, random_state=123)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1168, 303)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(292, 303)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_test.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br><br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 基础线性回归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.linear_model import LinearRegression\n",
    "from sklearn.metrics import mean_squared_error #方差"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "lm=LinearRegression()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None,\n",
       "         normalize=False)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lm.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "pred=lm.predict(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.12627809622157107"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.sqrt(mean_squared_error(np.log(y_test), np.log(pred)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "24973.913406557556"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.sqrt(mean_squared_error(y_test, pred))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "def benchmark(model):\n",
    "    pred = model.predict(X_test)\n",
    "    # 方差\n",
    "    logrmse = np.sqrt(mean_squared_error(np.log(y_test), np.log(pred)))\n",
    "    return logrmse"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.12627809622157107"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "benchmark(lm)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 数据预处理 Preprocessing\n",
    "\n",
    "先用机器学习参数去跑结果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.pipeline import make_pipeline\n",
    "from sklearn.preprocessing import RobustScaler"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 把机器学习方法，直接放进 make_pipeline\n",
    "lm_model = make_pipeline(RobustScaler(), LinearRegression())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Pipeline(memory=None,\n",
       "     steps=[('robustscaler', RobustScaler(copy=True, quantile_range=(25.0, 75.0), with_centering=True,\n",
       "       with_scaling=True)), ('linearregression', LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None,\n",
       "         normalize=False))])"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 将数据变换后的数据，进行机器学习\n",
    "lm_model.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.1262780962215701"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 评测模型\n",
    "benchmark(lm_model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.12627809622157107"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "benchmark(lm)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br><br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## RidegeRegression"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 朴素的Ridge回归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.linear_model import Ridge"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "ridge_model = Ridge(alpha=0.1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Ridge(alpha=0.1, copy_X=True, fit_intercept=True, max_iter=None,\n",
       "   normalize=False, random_state=None, solver='auto', tol=0.001)"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ridge_model.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.12658320875064985"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "benchmark(ridge_model)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 数据预处理的Ridge回归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "ridge_model_pipe=make_pipeline(RobustScaler(), Ridge(alpha=0.1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Pipeline(memory=None,\n",
       "     steps=[('robustscaler', RobustScaler(copy=True, quantile_range=(25.0, 75.0), with_centering=True,\n",
       "       with_scaling=True)), ('ridge', Ridge(alpha=0.1, copy_X=True, fit_intercept=True, max_iter=None,\n",
       "   normalize=False, random_state=None, solver='auto', tol=0.001))])"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ridge_model_pipe.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.12658566764241647"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "benchmark(ridge_model_pipe)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 带有CV的Ridge回归\n",
    "\n",
    "cross view data K折交叉"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import KFold\n",
    "from sklearn.linear_model import RidgeCV"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [],
   "source": [
    "kfolds=KFold(n_splits=10, shuffle=True, random_state=123)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "r_alphas=[0.01, 0.1, 1, 3, 5, 7, 10, 100]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "ridge_model_cv=make_pipeline(RobustScaler(), RidgeCV(alphas=r_alphas, cv=kfolds))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "# RidgeCV()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Pipeline(memory=None,\n",
       "     steps=[('robustscaler', RobustScaler(copy=True, quantile_range=(25.0, 75.0), with_centering=True,\n",
       "       with_scaling=True)), ('ridgecv', RidgeCV(alphas=array([1.e-02, 1.e-01, 1.e+00, 3.e+00, 5.e+00, 7.e+00, 1.e+01, 1.e+02]),\n",
       "    cv=KFold(n_splits=10, random_state=123, shuffle=True),\n",
       "    fit_intercept=True, gcv_mode=None, normalize=False, scoring=None,\n",
       "    store_cv_values=False))])"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ridge_model_cv.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.12385966794851841"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "benchmark(ridge_model_cv)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "def benchmark2(model, testset, label):\n",
    "    pred=model.predict(testset)\n",
    "    if pred[pred<0.].shape[0]>0:\n",
    "        print('Neg Value') #拟合过程飞掉\n",
    "    rmse=np.sqrt(mean_squared_error(label, pred))\n",
    "    lrmse=np.sqrt(mean_squared_error(np.log(label), np.log(pred)))\n",
    "    print('RMSE:', rmse)\n",
    "    print('LRMSE:', lrmse)\n",
    "    return lrmse"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "RMSE: 26907.89401651115\n",
      "LRMSE: 0.12385966794851841\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0.12385966794851841"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "benchmark2(ridge_model_cv, X_test, y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [],
   "source": [
    "r_alphas2=[.0001, .0003, .0005, .0007, .0009, .01, 0.05, 0.1, 0.3, 1, 3, 5, 10, 15, 20, 30, 50, 60, 70, 80]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [],
   "source": [
    "def ridge_train_test(alpha):\n",
    "    m = make_pipeline(RobustScaler(), RidgeCV(alphas=[alpha], cv=kfolds))\n",
    "    m.fit(X_train, y_train)\n",
    "    return benchmark2(m, X_test, y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "RMSE: 24973.969249187514\n",
      "LRMSE: 0.12627904574538876\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0.12627904574538876"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ridge_train_test(.0001)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 要写很多很多野代码\n",
    "scores=[]\n",
    "for k in r_alphas2:\n",
    "    scores.append(ridge_train_test(k))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x1139eb9b0>]"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYQAAAD8CAYAAAB3u9PLAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4xLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvAOZPmwAAIABJREFUeJzt3Xl8VOXZ8PHflY0skIQlYQn7qgElQERBAbUiaB+hKiruWJe6teqjtrY+j1bf17d1q1ZrUWq1LnWhKkrVAqJYqwISkCUBEsKesCRsCUv2XO8fc4JjBDIJyZyZnOv7+eTDzH2WuSYznCv3cu5bVBVjjDEmwu0AjDHGhAZLCMYYYwBLCMYYYxyWEIwxxgCWEIwxxjgsIRhjjAEsIRhjjHFYQjDGGANYQjDGGOOIcjuAxujUqZP27t3b7TCMMSasLF26dJeqpjS0X1glhN69e5OVleV2GMYYE1ZEZHMg+1mTkTHGGMASgjHGGIclBGOMMYAlBGOMMQ5LCMYYYwBLCMYYYxyWEIwxxgCWEH6grLKG1xZtpqyyxu1QjDEmqCwh1DMnZzv/+342P3t9KRXVlhSMMd5hCaGelQUlREYIX+QV8/M3vqWqptbtkIwxJigsIdSTXVhCRo9kfntBOvNW7+TumSuoqVW3wzLGmBYXVnMZtbSaWiVnWymXZvZg2ul9KKuq5dE5a4mNjuD3F51MRIS4HaIxxrQYSwh+Nu46wKHKGoakJQFwy5n9KKuq4ZlP1xEXHclvJw1GxJKCMaZ1soTgZ1VhCQAnOQkB4K5zBlBWWc1f/rOR2JhI7pt4giUFY0yrFFAfgohMFJFcEckXkfuOsH2siCwTkWoRmeJX3sspXy4iOSJys9+2R0Rkq4gcaJ63cvxWFZQSGx1Bv5SEw2Uiwm/OP5GrTuvJC//ewDOf5rsYoTHGtJwGawgiEgk8B4wHCoAlIjJbVVf77bYFmAbcU+/w7cAoVa0QkbZAtnPsNuCfwJ+Adcf/NppHdmEJ6V0TiYr8fp4UER6eNITyqlqemp9H29gorj+jj0tRGmNMywikhjASyFfVDapaCbwFTPbfQVU3qepKoLZeeaWqVjhP2/i/nqouUtXtxxV9M6qtVXK2lXyvuchfRITw6MUnMz69M4/+ay2F+8qCHKExxrSsQBJCGrDV73mBUxYQEekhIiudczzq1A4CJiI3iUiWiGQVFxc35tBG2bDrIAf9OpSPJDJCePCCdBTl2U9DpmJjjDHNosXvQ1DVrap6MtAfuFZEOjfy+BmqmqmqmSkpDS4J2mTZdR3K3Y+eEAC6t4/nylN78Y+lBWwoDpnuD2OMOW6BJIRCoIff8+5OWaM4NYNsYExjjw2GVYUlxEZH0D+lbYP73nZWf2IiI3hqvtUSjDGtRyAJYQkwQET6iEgMMBWYHcjJRaS7iMQ5j9sDZwC5TQ22Ja0qLOHEI3QoH0lKuzb89Ize/HPFNlZvKw1CdMYY0/IavPqpajVwOzAXWAPMVNUcEXlYRCYBiMgpIlIAXAK8ICI5zuEnAotFZAXwb+AJVV3lHPOYc0y8iBSIyG+b+80FqrZWWb2t9Kgdykdy05h+JMZG8eS8kMxvxhjTaAHdmKaqHwMf1yt7wO/xEnxNSfWP+wQ4+Sjn/CXwy8YE21I27j7IgYrqY3Yo15cUH83PxvXj8bm5LN28hxG9OrRghMYY0/Jscjv8OpQbkRAArju9N53axvDYnFxUbQI8Y0x4s4QArCoooU1UBANSG+5Q9hcfE8XtZ/Vn8cY9fJm/q4WiM8aY4LCEQOM6lOu7/NSepCXH8fhcqyUYY8Kb5xNCrTPldWObi+q0iYrkjnMGsLKghLk5O5s5OmOMCR7PJ4RNTodyUxMCwEXD0uibksCT83JtMR1jTNjyfEKom/K6MSOM6ouKjODu8YNYV3SA979t9D17xhgTEjyfELILS4iJimBA58Z1KNd33pAuDO6WyFPz86istnWYjTHhx/MJoa5DOboJHcr+IiKEeycMomBvGW8v2dJM0RljTPB4OiHU1io5haWclJbYLOcbNzCFkb078Mxn+ZRV1jTLOY0xJlg8nRA27znE/uPsUPYnItwzYRDF+yt4ZeGmZjmnMcYEi6cTQnN0KNc3sk8HzhyUwvTP11NaXtVs5zXGmJbm6YRQ16E8sHO7Zj3vPecOoqSsihe/2NCs5zXGmJbk6YSwqqCEE7u0O+4O5fqGpCXx45O68uKXG9l1oKLhA4wxJgR4NiGoKtnbSpq1ucjfXeMHUl5Vw/TP17fI+Y0xprl5NiFs3n2I/eXN16FcX//Utlw8vDuvLdrMtn1lLfIaxhjTnDybEFqiQ7m+O84ZgKry7Ge21KYxJvR5NiFkF5YQE9n8Hcr+ureP58pTezEzq4CNuw622OsYY0xz8GxCWFVYwgld2xET1bK/gtvO6k9MZARPfZLXoq9jjDHHK6CroYhMFJFcEckXkfuOsH2siCwTkWoRmeJX3sspXy4iOSJys9+2ESKyyjnnMyIizfOWGqaqZBe2XIeyv5R2bfjpGb2ZvWIbq7eVtvjrGWNMUzWYEEQkEngOOA9IBy4XkfR6u20BpgFv1CvfDoxS1QzgVOA+EenmbJsO3AgMcH4mNvE9NNqWPYcobcEO5fpuGtOPxNgonpyXG5TXM8aYpgikhjASyFfVDapaCbwFTPbfQVU3qepKoLZeeaWq1g3Eb1P3eiLSFUhU1UXqW2bsVeAnx/dWAreqiWsoN1VSfDQ/G9ePT9cWsXTznqC8pjHGNFYgCSEN2Or3vMApC4iI9BCRlc45HlXVbc7xBU095/FaFYQO5fquO703ndrG8NgcW2rTGBOaWrxTWVW3qurJQH/gWhHp3JjjReQmEckSkazi4uJmiSm7sIRBXVq+Q9lffEwUt5/Vn8Ub9/Bl/q6gva4xxgQqkCtiIdDD73l3p6xRnJpBNjDGOb57IOdU1RmqmqmqmSkpKY192SNat/MAJ3QJXu2gzuWn9iQtOY7H51otwRgTegJJCEuAASLSR0RigKnA7EBOLiLdRSTOedweOAPIVdXtQKmInOaMLroG+KBJ76AJDlRUkxQXHayXO6xNVCR3nDOAlQUlzM3ZGfTXN8aYY2kwIahqNXA7MBdYA8xU1RwReVhEJgGIyCkiUgBcArwgIjnO4ScCi0VkBfBv4AlVXeVsuxV4EcgH1gP/asb3daz3Q1lVDfExkcF4uR+4aFgafVMSeHJeLjW1VkswxoSOqEB2UtWPgY/rlT3g93gJ328Cqiv/BDj5KOfMAoY0JtjmUFFdiyrEupQQoiIjuHv8IG57YxkfLC/kouE/+LUZY4wrPHen8iFnacv4aHcSAsB5Q7owuFsiT83Po7K6tuEDjDEmCDyYEKoB36gft0RECPdOGMTWPWW8nbW14QOMMSYIPJcQypwaQpxLTUZ1xg1MYWTvDvxxfh77DlW6GosxxoAHE8LhJiOXE4KI8NtJg9l7qIrffbzW1ViMMQY8nBDiXOxDqJPeLZEbx/Tl7aytLFy/2+1wjDEe57mEUF4VGk1Gde740QB6dojnN7NWHY7NGGPc4LmE8F2TkXudyv7iYiJ55MIhbNx1kOcW5LsdjjHGwzyYEOpGGYVGDQFgzIAULhqexvTP15O7Y7/b4RhjPMpzCaEsxJqM6vzPj9NpFxvFr99bSa3dwWyMcYHnEkKojDKqr0NCDP/7X+ks27KPvy/e7HY4xhgP8mxCiI0KrYQAcOGwNMYM6MSjc3LZUVLudjjGGI/xXEIor6ohNjqCiIigLeEcMBHhkZ+cRHVtLQ/OznY7HGOMx3guIRyqrA6ZEUZH0rNjPHeeM5C5OTuZk73D7XCMMR7iwYRQExI3pR3L9Wf04cSuiTw4O5vS8iq3wzHGeITnEkJZpXtrIQQqOjKC3190EsX7K3h8Tq7b4RhjPMJzCeFQZU3IDTk9kqE9kpk2ug+vL97M0s173A7HGOMBnksIZVWh32RU5+5zB9ItKY773l1l6yYYY1qc9xJCGDQZ1UloE8X/+clg1hUd4IV/r3c7HGNMKxdQQhCRiSKSKyL5InLfEbaPFZFlIlItIlP8yjNEZKGI5IjIShG5zG/b2c4x2SLyiogEZehPqI8yqu/sEzrzXyd35dnP8llffMDtcIwxrViDCUFEIoHngPOAdOByEUmvt9sWYBrwRr3yQ8A1qjoYmAg8LSLJIhIBvAJMVdUhwGbg2uN5I4EqC5M+BH8PXJBObHQEv3lvlU1rYYxpMYHUEEYC+aq6QVUrgbeAyf47qOomVV0J1NYrz1PVdc7jbUARkAJ0BCpVNc/Z9RPg4uN6JwE6VBU+TUZ1UtvF8pvzT2Txxj38Y6ktuWmMaRmBJIQ0wP8qVOCUNYqIjARigPXALiBKRDKdzVOAHo09Z1OEw30IR3JpZg9G9unAIx+toXh/hdvhGGNaoaB0KotIV+A14DpVrVVVBaYCT4nIN8B+4Iirw4jITSKSJSJZxcXFxxVHTa1SWV0bdk1GABERwu8uOonyqloe/nC12+EYY1qhQBJCId//6727UxYQEUkEPgLuV9VFdeWqulBVx6jqSOALIO9Ix6vqDFXNVNXMlJSUQF/2iOqmvg63JqM6/VLacvvZ/fnnim0sWFvkdjjGmFYmkISwBBggIn1EJAbfX/azAzm5s/8s4FVVfafetlTn3zbAr4DnGxN4U9QtjhMXRqOM6rt5XD8GpLblf97P5mBFtdvhGGNakQYTgqpWA7cDc4E1wExVzRGRh0VkEoCInCIiBcAlwAsikuMcfikwFpgmIsudnwxn270isgZYCfxTVT9r3rf2Q2V1ayGEYR9CnZioCH5/8UkU7ivjD58csVJljDFNEtCfyqr6MfBxvbIH/B4vwdeUVP+414HXj3LOe4F7GxPs8apbCyEc+xD8jejVgatO68nLX21kckY3Tu6e7HZIxphWwFN3Kofq8plN8cuJJ9CpbRvue3cVVTU2rYUx5vh5KyG0giajOomx0Tw8eTCrt5fy0pcb3Q7HGNMKeCohfLeecvh2KvubOKQr56Z35qn5eWzZfcjtcIwxYc5jCaFulFH41xDqPDR5MFEREdz//ip8t3cYY0zTeCohlLWSTmV/XZPi+OXEQfxn3S7eXx7w7SHGGPMDnkoIh1pRH4K/K0/txfCeyTz4QQ4bdx10OxxjTJjyVEJoTaOM/EVGCH+cOozICOHGV7PYb+swG2OawFsJobKGCIE2Ua3vbffoEM9zVw5n466D3PX2cpsm2xjTaK3vyngMhypriI+JQkTcDqVFjO7XiQcvSGf+miKe/CTX7XCMMWGmdYy/DFBZVXWray6q7+rTerFmeynPLVjPCV0SuWBoN7dDMsaECc/VEMJxLYTGEBEemjSEU3q35953VpBdWOJ2SMaYMOG5hBCuU183RkxUBNOvGkGH+BhuejXLFtQxxgTEUwmhvCr81lNuqk5t2zDjmkz2HKrklteXUllt8x0ZY47NUwnBKzWEOkPSknh8ylCyNu/lwdnZdiezMeaYPJcQ4qI91Y/OBUO7cdtZ/Xjzm628tmiz2+EYY0KYpxJCWWXrH2V0JHePH8Q5J6by0D9X8/X6XW6HY4wJUZ5KCIcqa1rdtBWBiIgQnrosgz6dErjt78vYusdmRjXG/JCnEkKZhzqV62sXG81frsmkpla58dUsW4/ZGPMD3koIHutUrq9PpwT+dMVw8nbu5+6ZK2x6C2PM9wSUEERkoojkiki+iNx3hO1jRWSZiFSLyBS/8gwRWSgiOSKyUkQu89v2I+eY5SLypYj0b563dGSV1bVU16qnEwLA2IEp/Ob8E5mTs4NnPlvndjjGmBDSYEIQkUjgOeA8IB24XETS6+22BZgGvFGv/BBwjaoOBiYCT4tI3Yrw04ErVTXDOe5/mvomAvHdWgjeGmV0JNef0YeLh3fn6fnrmJO93e1wjDEhIpAawkggX1U3qGol8BYw2X8HVd2kqiuB2nrleaq6znm8DSgCUuo2A4nO4yRgW5PfRQAOVTmrpXmwU7k+EeGRC4eQ0SOZ/565grU7St0OyRgTAgJJCGnAVr/nBU5Zo4jISCAGWO8U3QB8LCIFwNXA749y3E0ikiUiWcXFxY192cO+W0/ZEgJAbHQkM64eQbvYKG54JYs9ByvdDskY47KgdCqLSFfgNeA6Va2rRdwFnK+q3YGXgT8c6VhVnaGqmaqamZKScqRdAtIal888XqmJscy4OpOi/RXc+velVNXY9BbGeFkgCaEQ6OH3vLtTFhARSQQ+Au5X1UVOWQowVFUXO7u9DYwO9JxNUbdamtUQvm9oj2QevfgkFm3Yw//5cLXb4RhjXBRIQlgCDBCRPiISA0wFZgdycmf/WcCrqvqO36a9QJKIDHSejwfWBB5241mT0dFdOKw7N43ty6sLN/PmN1vcDscY45IGE4KqVgO3A3PxXbRnqmqOiDwsIpMAROQUpy/gEuAFEclxDr8UGAtMc4aXLheRDOecNwLvisgKfH0I9zb7u/NTVunrVI61TuUj+tXEExg7MIUHPshmyaY9bodjjHGBhNMMmJmZmZqVldWkY99bVsB/z1zBgnvOpE+nhGaOrHUoOVTFT/78FaVlVcz++RmkJce5HZIxphmIyFJVzWxoP8/cqWx9CA1LivdNb1FZXctPX17CztJyt0MyxgSRdxKCjTIKSP/Utjx/9Qi27j3ERX/+mvyi/W6HZIwJEs8khMOdytaH0KDT+3di5s9GUVFdy8XTF1qfgjEe4amEEBMZQVSkZ97ycRmSlsSsW0fTMSGGK19czL9W2RQXxrR2nrk6llfV0CbaM2+3WfToEM87t4xmSLdEbn1jGS9/tdHtkIwxLcgzV8iK6lraRFlzUWN1SIjhjRtPY/yJnXnon6v53cdrbNpsY1opzySEyupa2kR55u02q9joSKZfNYJrRvXihS82cOfby6mornE7LGNMM/PMXNCVNbXEWEJossgI4aFJg+maFMejc9ZSvL+C568eQVJctNuhGWOaiWeukJXVvk5l03Qiwi1n9uOpy4aStXkPlz6/kO0lZW6HZYxpJp65QlZWWw2huVw4rDt/u24khfvKuOjPX5O7w+5VMKY18MwV0pqMmlfdvQq1qkx5/msWrt/tdkjGmOPkmStkZXUt0ZHidhitSnq3RN679XQ6J8Zy7UvfMHtFiy56Z4xpYZ5KCDE27LTZpSXH8e7No8nokcwv3vyWv3yxgXCaMNEY8x3vJIQatU7lFpIUH82r14/kxyd15ZGP1/Dwh6upsXsVjAk73hl2Wl1j9yG0oNjoSJ69fBidE2N56auN7Cwt5w+XZtj6E8aEEe8kBOtUbnEREcIDF6TTLTmW//vRGnbt/4YZ14wgOT7G7dCMMQHwzBWysrrWmoyC5IYxfXn28mEs37qPKc8vpGDvIbdDMsYEwDNXSLsPIbguGNqNV346kp2l5Vz056/J2VbidkjGmAYEdIUUkYkikisi+SJy3xG2jxWRZSJSLSJT/MozRGShiOSIyEoRucxv23/81lneJiLvN89bOjJLCME3ql9H3r1lNJERwmUvLOLLdbvcDskYcwwNXiFFJBJ4DjgPSAcuF5H0erttAaYBb9QrPwRco6qDgYnA0yKSDKCqY1Q1Q1UzgIXAe8fzRhpifQjuGNi5HbNuPZ3u7eOY9vI3zPq2wO2QjDFHEcgVciSQr6obVLUSeAuY7L+Dqm5S1ZVAbb3yPFVd5zzeBhQBKf77iEgicDbQYjWE2lqlqkaJtj4EV3RJimXmzaM4pXcH7np7BX/+PN/uVTAmBAVyhUwDtvo9L3DKGkVERgIxwPp6m34CfKqqpUc57iYRyRKRrOLi4sa+LOCrHQA27NRFibHR/O2npzBpaDcem5PL/36QbfcqGBNignKFFJGuwGvAdapaW2/z5cCbRztWVWeoaqaqZqakpBxtt2OqchKCjTJyV5uoSJ6+LIOfjevL64u2cMvrSymvsnUVjAkVgVwhC4Eefs+7O2UBcZqEPgLuV9VF9bZ1wtck9VGg52uKymonIVgNwXUREcKvzzuRhyYN5pM1O7niL4vYc7DS7bCMMQSWEJYAA0Skj4jEAFOB2YGc3Nl/FvCqqr5zhF2mAB+qanmgATdFXZORJYTQce3o3ky/cjjZ20qZMv1rtuy2exWMcVuDV0hVrQZuB+YCa4CZqpojIg+LyCQAETlFRAqAS4AXRCTHOfxSYCwwzW+IaYbf6adyjOai5nK4hmBNRiFl4pCuvHHDqew+WMlF079iVYHdq2CMmwKaukJVPwY+rlf2gN/jJfiakuof9zrw+jHOe2aggR4PazIKXZm9O/DuLaO59qVvuGzGQp67cjhnDUp1OyxjPMkTV8gKSwghrX9qW2bdOpo+nRK44ZUsZmZtbfggY0yz88QVstJGGYW81MRY3v7ZKEb368gv31nJH+evs3sVjAkyT1whrckoPLRtE8VL007houFpPDU/j9/MWkV1Tf1RysaYluKJ6a+rbJRR2IiOjODJS4bSLSmOPy3IZ2dpBX+6YhjxMZ74qhrjKk9cIW2UUXgREe6ZMIhHLhzC57lFXD5jEbsOVLgdljGtnieukNZkFJ6uPLUXL1ydSe7O/Vw8/Ws27TrodkjGtGqeuEKWOdMjxNlyjmFnfHpn3rjxNPaXV3PR9K/5dstet0MyptXyVkKIsYQQjob3bM+7t4ymbZsopjy/kF+9s5LCfWVuh2VMq+ONhFBpCSHc9emUwAe3nc41o3ox69tCznr8c347O4fi/da3YExz8VZCsCajsNY+IYYHLxjMgnvP5MJhaby2aDNjH1vA43PXUnKoyu3wjAl7nkgIBytriImMsAVyWom05DgenXIyn9w1lnPSO/PcgvWMeewznluQz8GKarfDMyZseeIKWVJWSVJ8tNthmGbWN6Utz14+jI9/MYaRfTrw+Nxcxj2+gJe+3GjrLBjTBB5JCFUkxtqNTa1VerdEXrz2FN69ZTT9U9vy8IerOfuJz3l7yRa709mYRvBEQqisrqVNlPUftHYjerXnzRtP4/XrTyUlMZZfvbuK8U99wewV26i15TqNaZAnEkJiXDRdkmLdDsMEgYhwxoBOvH/raGZcPYKYyAh+8ea3nP/Mf/h0zU6bMM+YY5Bw+g+SmZmpWVlZbodhwkhNrfLhym384ZM8Nu8+xLCeydw7YRCj+3VyOzRjgkZElqpqZkP7eaKGYLwrMkKYnJHG/P8ex/+78CS27yvnir8s5soXF9ldz8bUYzUE4ynlVTW8vmgzf/58PXsOVjI+vTN3nzuQE7okuh2aMS2mWWsIIjJRRHJFJF9E7jvC9rEiskxEqkVkil95hogsFJEcEVkpIpf5bRMReURE8kRkjYj8ItA3Z0xTxUZHcsOYvnzxy7O4e/xAFq3fzXl//A93vPWtTZ5nPK/BGoKIRAJ5wHigAFgCXK6qq/326Q0kAvcAs1X1Had8IKCquk5EugFLgRNVdZ+IXAecBUxT1VoRSVXVomPFYjUE09z2HarkhS828PJXG6mqUS7N7MEvftSfrklxbodmTLMJtIYQyOD8kUC+qm5wTvwWMBk4nBBUdZOz7XuDvlU1z+/xNhEpAlKAfcAtwBWqWutsP2YyMKYlJMfH8KuJJ3Dd6N48tyCfN77ZwrvLCrj6tF7cemY/OrZt43aIxgRNIE1GaYD/qucFTlmjiMhIIAZY7xT1Ay4TkSwR+ZeIDGjsOY1pLqmJsTw0eQif3X0mk4d24+WvNjL2sQU8OS+XkjKbJ8l4Q1BGGYlIV+A14Lq6GgHQBih3qjF/AV46yrE3OUkjq7i4OBjhGg/r0SGexy8Zyry7xnHmoFSe/SyfsY8tYPrn6zlUafMkmdYtkIRQCPTwe97dKQuIiCQCHwH3q+oiv00FwHvO41nAyUc6XlVnqGqmqmampKQE+rLGHJf+qW157srhfPjzMxjeM5lH56xl3OOf88rXm6iotnmSTOsUSEJYAgwQkT4iEgNMBWYHcnJn/1nAq3UdzX7ex9epDDAOX8e1MSFlSFoSL183knduHkWfTgk8ODuHs5/4N//I2mrzJJlWJ6D7EETkfOBpIBJ4SVUfEZGHgSxVnS0ip+C78LcHyoEdqjpYRK4CXgZy/E43TVWXi0gy8HegJ3AAuFlVVxwrDhtlZNykqvxn3S4en5vLqsIS+qYkcPf4QZw3pAsREeJ2eMYcVaCjjOzGNGMaSVWZm7ODJ+flsa7oAOldE7l3wiDOHJSCiCUGE3ps6gpjWoiIMHFIV+bcOZY/XDqU/RVVXPe3JVzy/EIWb9jtdnjGNJnVEIw5TpXVtczM2sozn66jaH8FYwZ04t4Jgzi5e7LboRkDWJORMUFXXlXDqws3Mf3z9ew9VMXEwV24+9yBDOjczu3QjMdZQjDGJfvLq/jrlxt58T8bOVhZzYUZadx5zkB6dox3OzTjUZYQjHHZnoOVvPDv9fzt603U1CpTR/bg52cPoHOiLdZkgssSgjEhYmdpOc9+to63vtlKZIRw7eje3DyuHx0SYtwOzXiEJQRjQsyW3Yd4+tM8Zn1bSEJMFNef0YcbxvShXWy026GZVs4SgjEhKm/nfv4wL485OTtoHx/NLWf245pRvYmNjnQ7NNNKWUIwJsStLNjHE/Py+CKvmM6Jbbj97AFcltmDmCi7Pcg0L0sIxoSJxRt288S8XJZs2kuPDnHc+aOB/GRYGpE2HYZpJnansjFh4tS+HZn5s1G8fN0pJMZGc/c/VjDx6S+Yk72dcPqDzYQ/SwjGhAAR4axBqfzz9jP485XDqVXl5teXMelPX/HvvGJLDCYoLCEYE0IiIoTzT+rK3DvH8viUk9lzsJJrX/qGy2YsYsmmPW6HZ1o560MwJoRVVNfw9pKtPPtZPsX7KzhrUAp3nzuIIWlJbodmwoh1KhvTipRV1vDKQt88SSVlVfz4pK7cNX4g/VPbuh2aCQOWEIxphUrLq3jxiw389cuNlFXVcNHw7tzxowH06GDzJJmjs4RgTCu2+0AF0z9fz6uLNqOqXDGyJ7ed3Z/UdjZPkvkhSwjGeMD2kjKe+TSff2RtJSpSmDa6DzeP60tyvM2TZL7TrPchiMhEEckVkXwRue8I28cbJ360AAAM80lEQVSKyDIRqRaRKX7lGSKyUERyRGSliFzmt+1vIrJRRJY7PxmBvjljjE/XpDh+d9FJzP/vcUwc3IUXvljPmEcX8Oyn6zhQUe12eCbMNFhDEJFIIA8YDxQAS4DLVXW13z69gUTgHmC2qr7jlA8EVFXXiUg3YClwoqruE5G/AR/W7RsIqyEYc2y5O/bz5Lxc5q3eSYeEGG4c05dJGd1IS45zOzTjokBrCFEBnGskkK+qG5wTvwVMBg4nBFXd5Gyr9T9QVfP8Hm8TkSIgBdgXwOsaYxppUJd2zLgmk+Vb9/HE3FwenbOWR+esZUhaIhPSuzBhSBcGpLZFxKbFMD8USEJIA7b6PS8ATm3sC4nISCAGWO9X/IiIPAB8CtynqhWNPa8x5ocyeiTz+g2nsnHXQebm7GBezg6e/CSPJz/Jo3fHeCYM7sK5g7swrEcyETZnknEEkhCOm4h0BV4DrlXVulrEr4Ed+JLEDOBXwMNHOPYm4CaAnj17BiNcY1qNPp0SuHlcP24e14+i0nLmrd7J3Jwd/PXLjbzwxQZS2rVhfHpnJgzuwqi+HW2mVY8LJCEUAj38nnd3ygIiIonAR8D9qrqorlxVtzsPK0TkZXz9Dz+gqjPwJQwyMzPDZ0iUMSEmNTGWq07rxVWn9aKkrIrPc4uYm7OD978t5I3FW2gXG8XZJ6RybnoXzhyUQkKboPy9aEJIIJ/4EmCAiPTBlwimAlcEcnIRiQFmAa/W7zwWka6qul18jZk/AbIbFbkxpsmS4qKZnJHG5Iw0yqtq+Cp/F3NzdjB/TREfLN9GTFQEY/p3YsLgLvzoxFQ6tm3jdsgmCAK6D0FEzgeeBiKBl1T1ERF5GMhS1dkicgq+C397oBzYoaqDReQq4GUgx+9001R1uYh8hq+DWYDlwM2qeuBYcdgoI2NaVnVNLVmb9zr9Djsp3FdGhEBm7w6+fof0znZXdBiyG9OMMcdFVcnZVsq8nB3MW72TtTv2AzC4WyLnpndhwpDODOrczkYshQFLCMaYZrVp10Hmrd7B3JydLNuyF1XoVTdiKb0zw3u2txFLIcoSgjGmxRTtL2f+al+n9Nfrd1FVo3RqWzdiqTOj+nWkTVSk22EahyUEY0xQlJZXsWBtEfNW7+TztUUcrKyhXZsozjwhlQmDO3PmoFTa2oglV1lCMMYEXXlVDV+v38Xc7J3MX7OT3QcriYmM4PT+HZkwuAvnpHemk41YCjpLCMYYV9XUKkudEUtzc3ZQsNcZsdSrA+ekp3JK7w4M7pZkN8MFgSUEY0zIUFXWbN9/ODnUjViKiYpgaPckhvdqz4ie7Rneq73VIFqAJQRjTMgqKi1n2Za9LN3s+8kuLKWyxjerTe+O8b4E4fwMSG1HpI1eOi6WEIwxYaO8qoacbSWHE8TSzXvZdaASgHZtosjomXw4QWT0SKZdbLTLEYeX5pz+2hhjWlRsdCQjenVgRK8OgK+JaeueMpZu2eMkiH388dN1qIIIDOrc7nCCGNGrPT07xNsNcs3AagjGmLCwv7yKFVudWsSWvXy7eS/7nVXhOrWNYXjP7xLEkLQkYqPtPog6VkMwxrQq7WKjOWNAJ84Y0AnwjWLKLzpwuIlp2Za9zFu9E4DoSGFIWhIjnCQxvFd7OifGuhl+WLAagjGm1dh9oIJlW/b5EsTmvawo2EdFta+zunv7uMM1iOE923NCl3ZERXpjyKvVEIwxntPRmT5jfHpnACqra1m9vfRwgli0YTcfLN8GQHxMJEO7f9dZPaxnMsnxMW6G7zqrIRhjPENV2VZSfjhBLN28l9XbS6mp9V0H+6YkMDC1Hf1SE+if2pZ+Kb6fcF8syGoIxhhTj4iQlhxHWnIck4Z2A+BQZTUrtpawbMteVmzdR17Rfj5Zs/NwkgDomhRLv5S2TpJIoF9qW/qntCWlXZtWNbrJEoIxxtPiY6IY1a8jo/p1PFxWWV3Llj2HyC86wPriA6x3/v1H1lYOVtYc3q9dbNThWkRdsuif2paeHeLDsn/CEoIxxtQTExVB/1TfRd6fqrKztOJwoqj798v8Yt5dVnB4v+hIoXfHhO8SRWoC/VPa0TclIaSbn0I3MmOMCTEiQpekWLokxR4e/lqntLyKDcUHv5csjtb8dLh/wq9WkdLW/eYnSwjGGNMMEmOjyeiRTEaP5O+V+5qf6hLFQdYXHSD/KM1PdYniuw7thKA2PwWUEERkIvBHIBJ4UVV/X2/7WOBp4GRgqqq+45RnANOBRKAGeERV36537DPAT1X1+3UzY4xpBXzNT+3on9rue+Wqyo7SctYXHSS/aD/rndrFF3nFvLP0h81P068a8YMmrObWYEIQkUjgOWA8UAAsEZHZqrrab7ctwDTgnnqHHwKuUdV1ItINWCoic1V1n3PuTKD98b8NY4wJLyJC16Q4uibF/aD5qaSsig3FBw4nifXFB+iY0PL3SARSQxgJ5KvqBgAReQuYDBxOCKq6ydlW63+gqub5Pd4mIkVACrDPSTSPA1cAFx7f2zDGmNYjKS6aYT3bM6xncP9eDqRhKg3Y6ve8wClrFBEZCcQA652i24HZqrq9geNuEpEsEckqLi5u7MsaY4wJUFB6KkSkK/AacJ2q1jrNR5cAzzZ0rKrOUNVMVc1MSUlp6VCNMcazAkkIhUAPv+fdnbKAiEgi8BFwv6oucoqHAf2BfBHZBMSLSH6g5zTGGNP8AulDWAIMEJE++BLBVHzt/g0SkRhgFvBq3cgjAFX9COjit98BVe3fmMCNMcY0rwZrCKpaja+9fy6wBpipqjki8rCITAIQkVNEpABfM9ALIpLjHH4pMBaYJiLLnZ+MFnknxhhjjovNdmqMMa1coLOdht/sS8YYY1qEJQRjjDFAmDUZiUgxsLmJh3cCdjVjOM3F4moci6txLK7Gaa1x9VLVBsfth1VCOB4ikhVIG1qwWVyNY3E1jsXVOF6Py5qMjDHGAJYQjDHGOLyUEGa4HcBRWFyNY3E1jsXVOJ6OyzN9CMYYY47NSzUEY4wxx+CJhCAiE0UkV0TyReQ+F+N4SUSKRCTbr6yDiHwiIuucf4O+YJCI9BCRBSKyWkRyROSOUIhNRGJF5BsRWeHE9ZBT3kdEFjuf59vOnFlBJSKRIvKtiHwYKjE5cWwSkVXONDFZTlkofMeSReQdEVkrImtEZJTbcYnIIL8pdZaLSKmI3Ol2XE5sdznf+WwRedP5v9Di37FWnxD8Vnw7D0gHLheRdJfC+RswsV7ZfcCnqjoA+NR5HmzVwN2qmg6cBtzm/I7cjq0COFtVhwIZwEQROQ14FHjKmRBxL3B9kOMCuAPf3F51QiGmOmepaobfMEW3P0fwLcE7R1VPAIbi+925Gpeq5jq/pwxgBL4VHme5HZeIpAG/ADJVdQi+pYunEozvmKq26h9gFDDX7/mvgV+7GE9vINvveS7Q1XncFcgNgd/ZB/iWTA2Z2IB4YBlwKr4bdKKO9PkGKZbu+C4UZwMfAuJ2TH6xbQI61Stz9XMEkoCNOH2WoRJXvVjOBb4Khbj4blGyDvhmpP4QmBCM71irryHQTCu+taDO+t2qcTuAzm4GIyK98a1XsZgQiM1pmlkOFAGf4Ftxb5/6ZuEFdz7Pp4FfAnVLxnYMgZjqKDBPRJaKyE1OmdufYx+gGHjZaWZ7UUQSQiAuf1OBN53HrsalqoXAE/jWqt8OlABLCcJ3zAsJIWyoL/W7NuxLRNoC7wJ3qmqp/za3YlPVGvVV6bvjW9/7hGDH4E9E/gsoUtWlbsZxDGeo6nB8TaS3ichY/40ufY5RwHBguqoOAw5SrxnGze++0xY/CfhH/W1uxOX0WUzGl0i7AQn8sKm5RXghIRzXim9BsNNZYrRuqdEiN4IQkWh8yeDvqvpeKMUGoKr7gAX4qsrJIlK3uFOwP8/TgUniW+nvLXzNRn90OabDnL8uUdUifO3hI3H/cywAClR1sfP8HXwJwu246pwHLFPVnc5zt+M6B9ioqsWqWgW8h+971+LfMS8khMMrvjl/CUwFZrsck7/ZwLXO42vxtd8HlYgI8Fdgjar+IVRiE5EUEUl2Hsfh69dYgy8xTHEjLlX9tap2V9Xe+L5Ln6nqlW7GVEdEEkSkXd1jfO3i2bj8OarqDmCriAxyin4ErHY7Lj+X811zEbgf1xbgNBGJd/5v1v2+Wv475lYnTpA7ac4H8vC1P9/vYhxv4msTrML3V9P1+NqfPwXWAfOBDi7EdQa+avFKYLnzc77bsQEnA986cWUDDzjlfYFvgHx81fw2Ln2eZwIfhkpMTgwrnJ+cuu+625+jE0MGkOV8lu8D7UMkrgRgN5DkVxYKcT0ErHW+968BbYLxHbM7lY0xxgDeaDIyxhgTAEsIxhhjAEsIxhhjHJYQjDHGAJYQjDHGOCwhGGOMASwhGGOMcVhCMMYYA8D/BzsQkORN+HWCAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1138149b0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 每一个alpha 的表现情况\n",
    "plt.plot(r_alphas2, scores)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### RidgeCV自动筛选参数\n",
    "找到 alpha 最好的参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 从e-10,到e2.8 平均抽样150个\n",
    "r_alphas3=np.logspace(-10, 2.8, 150)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "scores=[]\n",
    "for k in r_alphas3:\n",
    "    scores.append(ridge_train_test(k))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x115e96e10>]"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x112f61470>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(r_alphas3, scores)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以使用自动优化筛选出最优的alpha"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [],
   "source": [
    "ridge_model2 = make_pipeline(RobustScaler(), RidgeCV(\n",
    "        alphas=r_alphas3, cv=kfolds\n",
    ")).fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "RMSE: 25983.546991372652\n",
      "LRMSE: 0.12570253861398775\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0.12570253861398775"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "benchmark2(ridge_model2, X_test, y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[('robustscaler',\n",
       "  RobustScaler(copy=True, quantile_range=(25.0, 75.0), with_centering=True,\n",
       "         with_scaling=True)),\n",
       " ('ridgecv',\n",
       "  RidgeCV(alphas=array([1.00000e-10, 1.21873e-10, ..., 5.17719e+02, 6.30957e+02]),\n",
       "      cv=KFold(n_splits=10, random_state=123, shuffle=True),\n",
       "      fit_intercept=True, gcv_mode=None, normalize=False, scoring=None,\n",
       "      store_cv_values=False))]"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ridge_model2.steps"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "39.56538865832277"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 最好的alpha\n",
    "ridge_model2.steps[1][1].alpha_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 和曲线得到的最优alpha不一样？\n",
    "- 图表示全部是测试集，最好的alpha\n",
    "- 自动化筛选，是不知道测试集合的分布的\n",
    "  - 既参考了训练集的均值、方差、loss，也考虑了模型复杂度，挑出来是最优的\n",
    "  - `steps[1][1].alpha_` 更科学\n",
    "- 单把20%数据当测试集是不对的，比赛时不根本不知道评测集的"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br><br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## LassoRegression"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 带有CV的Lasso回归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.linear_model import LassoCV"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [],
   "source": [
    "l_alphas=np.logspace(-10, 2.8, 150)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [],
   "source": [
    "def lasso_train_test(alpha):\n",
    "    lasso_model = make_pipeline(RobustScaler(), LassoCV(alphas=[alpha], cv=kfolds))\n",
    "    lasso_model.fit(X_train, y_train)\n",
    "    lrmse = benchmark2(lasso_model, X_test, y_test)\n",
    "    return lrmse"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "scores = []\n",
    "for k in l_alphas:\n",
    "    print(\"Alpha:\", k)\n",
    "    scores.append(lasso_train_test(k))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x11667d2e8>]"
      ]
     },
     "execution_count": 76,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1169afa20>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(l_alphas, scores)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "RMSE: 24601.931715190687\n",
      "LRMSE: 0.11575377693141331\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0.11575377693141331"
      ]
     },
     "execution_count": 77,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 仅仅代表我们分出来的测试集，并不代表线上另外的测试集\n",
    "lasso_train_test(50)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### LassoCV自动筛选参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [],
   "source": [
    "lasso_model2=make_pipeline(RobustScaler(), LassoCV(\n",
    "    alphas=l_alphas, cv=kfolds\n",
    ")).fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "RMSE: 25431.111829508853\n",
      "LRMSE: 0.12203176481488645\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0.12203176481488645"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "benchmark2(lasso_model2, X_test, y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "192.5589718453296"
      ]
     },
     "execution_count": 72,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lasso_model2.steps[1][1].alpha_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br><br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## ElasticNet"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 带有CV的ElasticNet回归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.linear_model import ElasticNetCV"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {},
   "outputs": [],
   "source": [
    "e_l1ratio = [0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.85,0.9,0.95,1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [],
   "source": [
    "e_alphas = l_alphas"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [],
   "source": [
    "def elastic_train_test(alpha, l1ratio):\n",
    "    e_model = make_pipeline(RobustScaler(), ElasticNetCV(\n",
    "        alphas=[alpha], l1_ratio=[l1ratio]\n",
    "    )).fit(X_train, y_train)\n",
    "    lrmse = benchmark2(e_model, X_test, y_test)\n",
    "    return lrmse"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "RMSE: 64803.88956616406\n",
      "LRMSE: 0.3056812482960621\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0.3056812482960621"
      ]
     },
     "execution_count": 87,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "elastic_train_test(50,0.5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### ElasticNetCV自动筛选参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {},
   "outputs": [],
   "source": [
    "elastic_model2 = make_pipeline(RobustScaler(), ElasticNetCV(\n",
    "    alphas=e_alphas, l1_ratio=e_l1ratio\n",
    ")).fit(X_train,y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "RMSE: 25431.111829508853\n",
      "LRMSE: 0.12203176481488645\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0.12203176481488645"
      ]
     },
     "execution_count": 89,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "benchmark2(elastic_model2, X_test, y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "192.5589718453296"
      ]
     },
     "execution_count": 92,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "elastic_model2.steps[1][1].alpha_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.0"
      ]
     },
     "execution_count": 91,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "elastic_model2.steps[1][1].l1_ratio_"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4rc1"
  },
  "toc-autonumbering": false
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
